#!/bin/bash
# CentOS多环境部署脚本 v4.1
# 作者：YourName
# 日期：2025-08-23
# 功能：自动化部署JDK、MySQL、NGINX、Tomcat、Redis等环境
# 兼容性：CentOS 7+

# 全局配置
INSTALL_BASE="/root/soft"
LOG_FILE="/var/log/centos_env_setup.log"
BACKUP_DIR="/root/backup/$(date +%Y%m%d_%H%M%S)"
TIMESTAMP() { date +"%Y-%m-%d %H:%M:%S"; }
log() { echo "[$(TIMESTAMP)] $1" | tee -a $LOG_FILE; }
error_log() { echo "[$(TIMESTAMP)] ERROR: $1" | tee -a $LOG_FILE >&2; }

# 颜色输出
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m' # No Color

# 权限检查
check_permissions() {
    if [ "$(id -u)" != "0" ]; then
        echo -e "${RED}必须使用root权限运行！${NC}" >&2
        exit 1
    fi
}

# 系统检查
check_system() {
    log "检查系统环境..."
    
    # 检查操作系统
    if [ ! -f /etc/redhat-release ]; then
        error_log "此脚本仅支持CentOS/RHEL系统"
        exit 1
    fi
    
    # 检查CentOS版本
    CENTOS_VERSION=$(cat /etc/redhat-release | grep -oE '[0-9]+\.[0-9]+' | head -1)
    log "检测到CentOS版本: $CENTOS_VERSION"
    
    # 检查内存
    MEMORY=$(free -m | awk 'NR==2{printf "%.0f", $2}')
    if [ $MEMORY -lt 2048 ]; then
        error_log "系统内存不足，建议至少2GB内存"
        exit 1
    fi
    
    # 检查磁盘空间
    DISK_SPACE=$(df -m / | awk 'NR==2{printf "%.0f", $4}')
    if [ $DISK_SPACE -lt 10240 ]; then
        error_log "磁盘空间不足，建议至少10GB可用空间"
        exit 1
    fi
    
    log "系统检查通过 - 内存: ${MEMORY}MB, 磁盘: ${DISK_SPACE}MB"
}

# 创建备份目录
create_backup() {
    mkdir -p $BACKUP_DIR
    log "备份目录创建: $BACKUP_DIR"
}

# 安装依赖包
install_dependencies() {
    log "安装系统依赖包..."
    
    # 更新yum缓存
    yum clean all && yum makecache
    
    # 安装必要的包
    yum install -y wget curl vim net-tools unzip tar gzip
    
    # CentOS 7特定包
    if [[ "$CENTOS_VERSION" == "7"* ]]; then
        yum install -y epel-release
        yum install -y systemd-sysv
    fi
    
    log "依赖包安装完成"
}

# JDK配置
configure_jdk() {
    log "开始配置JDK环境..."
    
    JDK_DIR="jdk1.8.0_461"
    JDK_PATH="$INSTALL_BASE/$JDK_DIR"
    
    if [ ! -d "$JDK_PATH" ]; then
        error_log "未找到JDK目录: $JDK_PATH"
        return 1
    fi
    
    # 备份现有配置
    if [ -f /etc/profile.d/java.sh ]; then
        cp /etc/profile.d/java.sh $BACKUP_DIR/
    fi
    
    log "配置JDK环境变量..."
    cat > /etc/profile.d/java.sh <<EOF
# Java环境配置
export JAVA_HOME=$JDK_PATH
export PATH=\$PATH:\$JAVA_HOME/bin
export CLASSPATH=.:\$JAVA_HOME/lib/dt.jar:\$JAVA_HOME/lib/tools.jar
EOF
    
    # 立即生效环境变量
    export JAVA_HOME=$JDK_PATH
    export PATH=$PATH:$JAVA_HOME/bin
    export CLASSPATH=.:$JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar
    
    # 验证JDK
    if $JDK_PATH/bin/java -version >/dev/null 2>&1; then
        log "JDK配置成功: $($JDK_PATH/bin/java -version 2>&1 | head -n 1)"
        return 0
    else
        error_log "JDK配置失败，请检查JDK安装"
        return 1
    fi
}

# MySQL部署
deploy_mysql() {
    log "开始部署MySQL..."
    
    MYSQL_DIR="mysql-8.0.43-linux-glibc2.17-x86_64-minimal"
    MYSQL_PATH="$INSTALL_BASE/$MYSQL_DIR"
    
    if [ ! -d "$MYSQL_PATH" ]; then
        error_log "MySQL目录不存在: $MYSQL_PATH"
        return 1
    fi
    
    # 检查MySQL是否已运行
    if systemctl is-active --quiet mysql 2>/dev/null; then
        log "MySQL服务已在运行，跳过部署"
        return 0
    fi
    
    # 备份现有配置
    if [ -f /etc/my.cnf ]; then
        cp /etc/my.cnf $BACKUP_DIR/
    fi
    
    # 创建mysql用户
    if ! id "mysql" &>/dev/null; then
        useradd -r -s /bin/false mysql
    fi
    
    log "初始化MySQL数据库..."
    mkdir -p /var/lib/mysql
    mkdir -p /var/log/mysql
    chown -R mysql:mysql $MYSQL_PATH
    chown -R mysql:mysql /var/lib/mysql
    chown -R mysql:mysql /var/log/mysql
    
    # 创建MySQL配置文件
    cat > /etc/my.cnf <<EOF
[mysqld]
user=mysql
basedir=$MYSQL_PATH
datadir=/var/lib/mysql
socket=/var/lib/mysql/mysql.sock
pid-file=/var/lib/mysql/mysql.pid
port=3306
bind-address=127.0.0.1
default-storage-engine=INNODB
character-set-server=utf8mb4
collation-server=utf8mb4_unicode_ci
max_connections=200
innodb_buffer_pool_size=256M
log-error=/var/log/mysql/error.log
slow_query_log=1
slow_query_log_file=/var/log/mysql/slow.log
long_query_time=2
skip-grant-tables=1

[mysql]
socket=/var/lib/mysql/mysql.sock
default-character-set=utf8mb4

[client]
socket=/var/lib/mysql/mysql.sock
default-character-set=utf8mb4
EOF
    
    # 初始化数据库
    log "初始化MySQL数据库..."
    $MYSQL_PATH/bin/mysqld --defaults-file=/etc/my.cnf --initialize-insecure --user=mysql
    
    if [ $? -ne 0 ]; then
        error_log "MySQL初始化失败"
        return 1
    fi
    
    # 配置systemd服务
    cat > /etc/systemd/system/mysql.service <<EOF
[Unit]
Description=MySQL Community Server
After=network.target

[Service]
Type=forking
ExecStart=$MYSQL_PATH/bin/mysqld --defaults-file=/etc/my.cnf
PIDFile=/var/lib/mysql/mysql.pid
User=mysql
Group=mysql
Restart=on-failure
RestartSec=5
LimitNOFILE=65535

[Install]
WantedBy=multi-user.target
EOF

    systemctl daemon-reload
    systemctl enable mysql
    
    # 启动MySQL
    log "启动MySQL服务..."
    systemctl start mysql
    
    # 等待MySQL启动
    sleep 15
    
    if systemctl is-active --quiet mysql; then
        log "MySQL部署成功，服务已启动"
        
        # 等待MySQL完全启动后再设置密码
        sleep 5
        
        # 设置root密码
        $MYSQL_PATH/bin/mysql -u root -e "ALTER USER 'root'@'localhost' IDENTIFIED BY 'Bailian@2025'; FLUSH PRIVILEGES;" 2>/dev/null
        
        # 移除skip-grant-tables
        sed -i 's/skip-grant-tables=1/#skip-grant-tables=1/' /etc/my.cnf
        
        # 重启MySQL使配置生效
        systemctl restart mysql
        sleep 10
        
        if systemctl is-active --quiet mysql; then
            log "MySQL root密码已设置为: Bailian@2025"
            return 0
        else
            error_log "MySQL重启失败"
            return 1
        fi
    else
        error_log "MySQL启动失败，检查日志: /var/log/mysql/error.log"
        return 1
    fi
}

# NGINX配置
deploy_nginx() {
    log "开始部署NGINX..."
    
    NGINX_DIR="nginx-1.24.0"
    NGINX_PATH="$INSTALL_BASE/$NGINX_DIR"
    
    if [ ! -d "$NGINX_PATH" ]; then
        error_log "NGINX目录不存在: $NGINX_PATH"
        return 1
    fi
    
    # 检查NGINX是否已运行
    if systemctl is-active --quiet nginx 2>/dev/null; then
        log "NGINX服务已在运行，跳过部署"
        return 0
    fi
    
    # 备份现有配置
    if [ -f /etc/nginx/nginx.conf ]; then
        cp -r /etc/nginx $BACKUP_DIR/
    fi
    
    # 创建软链接
    ln -sf $NGINX_PATH /usr/local/nginx
    
    # 创建nginx用户
    if ! id "nginx" &>/dev/null; then
        useradd -r -s /bin/false nginx
    fi
    
    # 创建必要的目录
    mkdir -p /usr/local/nginx/logs
    mkdir -p /usr/local/nginx/conf
    chown -R nginx:nginx /usr/local/nginx
    
    # 配置systemd服务
    cat > /etc/systemd/system/nginx.service <<EOF
[Unit]
Description=The NGINX HTTP and reverse proxy server
After=syslog.target network.target

[Service]
Type=forking
PIDFile=/usr/local/nginx/logs/nginx.pid
ExecStartPre=/usr/local/nginx/sbin/nginx -t
ExecStart=/usr/local/nginx/sbin/nginx
ExecReload=/bin/kill -s HUP \$MAINPID
ExecStop=/bin/kill -s QUIT \$MAINPID
PrivateTmp=true
Restart=on-failure
RestartSec=5
LimitNOFILE=65535

[Install]
WantedBy=multi-user.target
EOF

    systemctl daemon-reload
    systemctl enable nginx
    
    # 启动NGINX
    log "启动NGINX服务..."
    systemctl start nginx
    
    if systemctl is-active --quiet nginx; then
        log "NGINX部署成功，服务已启动"
        log "NGINX访问地址: http://$(hostname -i)"
        return 0
    else
        error_log "NGINX启动失败，检查日志: /usr/local/nginx/logs/error.log"
        return 1
    fi
}

# Tomcat配置
deploy_tomcat() {
    log "开始部署Tomcat..."
    
    TOMCAT_DIR="apache-tomcat-10.1.44"
    TOMCAT_PATH="$INSTALL_BASE/$TOMCAT_DIR"
    
    if [ ! -d "$TOMCAT_PATH" ]; then
        error_log "Tomcat目录不存在: $TOMCAT_PATH"
        return 1
    fi
    
    # 检查Tomcat是否已运行
    if systemctl is-active --quiet tomcat 2>/dev/null; then
        log "Tomcat服务已在运行，跳过部署"
        return 0
    fi
    
    # 备份现有配置
    if [ -f /etc/profile.d/tomcat.sh ]; then
        cp /etc/profile.d/tomcat.sh $BACKUP_DIR/
    fi
    
    log "配置Tomcat环境..."
    ln -sf $TOMCAT_PATH /opt/tomcat
    
    # 创建tomcat用户
    if ! id "tomcat" &>/dev/null; then
        useradd -r -s /bin/false tomcat
    fi
    
    # 设置权限
    chown -R tomcat:tomcat /opt/tomcat
    chmod +x /opt/tomcat/bin/*.sh
    
    # 配置环境变量
    cat > /etc/profile.d/tomcat.sh <<EOF
# Tomcat环境配置
export CATALINA_HOME=/opt/tomcat
export CATALINA_BASE=/opt/tomcat
export PATH=\$PATH:\$CATALINA_HOME/bin
EOF
    
    source /etc/profile.d/tomcat.sh
    
    # 配置systemd服务
    cat > /etc/systemd/system/tomcat.service <<EOF
[Unit]
Description=Apache Tomcat Web Application Container
After=syslog.target network.target

[Service]
Type=forking
Environment=JAVA_HOME=$JDK_PATH
Environment=CATALINA_PID=/opt/tomcat/temp/tomcat.pid
Environment=CATALINA_HOME=/opt/tomcat
Environment=CATALINA_BASE=/opt/tomcat
ExecStart=/opt/tomcat/bin/startup.sh
ExecStop=/opt/tomcat/bin/shutdown.sh
User=tomcat
Group=tomcat
Restart=on-failure
RestartSec=10
LimitNOFILE=65535

[Install]
WantedBy=multi-user.target
EOF

    systemctl daemon-reload
    systemctl enable tomcat
    
    # 启动Tomcat
    log "启动Tomcat服务..."
    systemctl start tomcat
    
    # 等待Tomcat启动
    sleep 20
    
    if systemctl is-active --quiet tomcat; then
        log "Tomcat部署成功，服务已启动"
        log "Tomcat管理界面: http://$(hostname -i):8080"
        return 0
    else
        error_log "Tomcat启动失败，检查日志: /opt/tomcat/logs/catalina.out"
        return 1
    fi
}

# Redis配置
deploy_redis() {
    log "开始部署Redis..."
    
    REDIS_DIR="redis-stack-server-7.2.0-v6.catalina.x86_64"
    REDIS_PATH="$INSTALL_BASE/$REDIS_DIR"
    
    if [ ! -d "$REDIS_PATH" ]; then
        error_log "Redis目录不存在: $REDIS_PATH"
        return 1
    fi
    
    # 检查Redis是否已运行
    if systemctl is-active --quiet redis 2>/dev/null; then
        log "Redis服务已在运行，跳过部署"
        return 0
    fi
    
    # 备份现有配置
    if [ -f /etc/redis/redis.conf ]; then
        cp -r /etc/redis $BACKUP_DIR/
    fi
    
    # 创建redis用户
    if ! id "redis" &>/dev/null; then
        useradd -r -s /bin/false redis
    fi
    
    # 创建数据目录
    mkdir -p /var/lib/redis
    mkdir -p /var/log/redis
    chown redis:redis /var/lib/redis
    chown redis:redis /var/log/redis
    
    # 配置Redis
    cat > /etc/redis/redis.conf <<EOF
# Redis配置文件
bind 127.0.0.1
port 6379
daemonize yes
pidfile /var/run/redis/redis.pid
logfile /var/log/redis/redis.log
datadir /var/lib/redis
maxmemory 256mb
maxmemory-policy allkeys-lru
save 900 1
save 300 10
save 60 10000
requirepass Redis@2025
EOF
    
    # 创建pid目录
    mkdir -p /var/run/redis
    chown redis:redis /var/run/redis
    
    # 配置systemd服务
    cat > /etc/systemd/system/redis.service <<EOF
[Unit]
Description=Redis persistent key-value database
After=network.target

[Service]
Type=forking
ExecStart=/usr/bin/redis-server /etc/redis/redis.conf
ExecStop=/usr/bin/redis-cli -a Redis@2025 shutdown
User=redis
Group=redis
Restart=on-failure
RestartSec=5
LimitNOFILE=65535

[Install]
WantedBy=multi-user.target
EOF

    systemctl daemon-reload
    systemctl enable redis
    
    # 启动Redis
    log "启动Redis服务..."
    systemctl start redis
    
    if systemctl is-active --quiet redis; then
        log "Redis部署成功，服务已启动"
        log "Redis密码: Redis@2025"
        return 0
    else
        error_log "Redis启动失败，检查日志: /var/log/redis/redis.log"
        return 1
    fi
}

# 防火墙配置
configure_firewall() {
    log "配置防火墙规则..."
    
    if command -v firewall-cmd >/dev/null 2>&1; then
        # 开放必要端口
        firewall-cmd --permanent --add-port=80/tcp    # HTTP
        firewall-cmd --permanent --add-port=443/tcp   # HTTPS
        firewall-cmd --permanent --add-port=8080/tcp  # Tomcat
        firewall-cmd --permanent --add-port=3306/tcp  # MySQL
        firewall-cmd --permanent --add-port=6379/tcp  # Redis
        firewall-cmd --reload
        log "防火墙规则配置完成"
    else
        log "防火墙未安装，跳过配置"
    fi
}

# 安全配置
security_config() {
    log "配置安全设置..."
    
    # 禁用root SSH登录
    if [ -f /etc/ssh/sshd_config ]; then
        cp /etc/ssh/sshd_config $BACKUP_DIR/
        sed -i 's/#PermitRootLogin yes/PermitRootLogin no/' /etc/ssh/sshd_config
        systemctl reload sshd
        log "已禁用root SSH登录"
    fi
    
    # 设置文件权限
    chmod 600 /etc/my.cnf
    chmod 600 /etc/redis/redis.conf
    log "安全配置完成"
}

# 性能优化
performance_optimize() {
    log "配置性能优化..."
    
    # 系统参数优化
    cat >> /etc/sysctl.conf <<EOF

# 性能优化配置
net.core.somaxconn = 65535
net.core.netdev_max_backlog = 5000
net.ipv4.tcp_max_syn_backlog = 65535
net.ipv4.tcp_fin_timeout = 30
net.ipv4.tcp_keepalive_time = 1200
net.ipv4.tcp_max_tw_buckets = 5000
vm.swappiness = 10
EOF
    
    sysctl -p
    log "性能优化配置完成"
}

# 健康检查
health_check() {
    log "执行服务健康检查..."
    
    local failed_services=()
    
    # 检查各服务状态
    if ! systemctl is-active --quiet mysql 2>/dev/null; then
        failed_services+=("MySQL")
    fi
    
    if ! systemctl is-active --quiet nginx 2>/dev/null; then
        failed_services+=("NGINX")
    fi
    
    if ! systemctl is-active --quiet tomcat 2>/dev/null; then
        failed_services+=("Tomcat")
    fi
    
    if ! systemctl is-active --quiet redis 2>/dev/null; then
        failed_services+=("Redis")
    fi
    
    if [ ${#failed_services[@]} -eq 0 ]; then
        log "所有服务运行正常"
        return 0
    else
        error_log "以下服务运行异常: ${failed_services[*]}"
        return 1
    fi
}

# 清理函数
cleanup() {
    log "清理临时文件..."
    # 可以在这里添加清理逻辑
}

# 主执行流程
main() {
    log "========== $(TIMESTAMP) 环境部署开始 =========="
    
    # 执行检查
    check_permissions
    check_system
    create_backup
    install_dependencies
    
    # 部署服务
    local failed_deployments=()
    
    configure_jdk || failed_deployments+=("JDK")
    deploy_mysql || failed_deployments+=("MySQL")
    deploy_nginx || failed_deployments+=("NGINX")
    deploy_tomcat || failed_deployments+=("Tomcat")
    deploy_redis || failed_deployments+=("Redis")
    
    # 配置优化
    configure_firewall
    security_config
    performance_optimize
    
    # 健康检查
    health_check
    
    # 输出结果
    if [ ${#failed_deployments[@]} -eq 0 ]; then
        log "========== $(TIMESTAMP) 环境部署完成 =========="
        echo -e "${GREEN}所有服务部署成功！${NC}"
        echo -e "${BLUE}服务信息:${NC}"
        echo -e "  MySQL: 端口3306, 密码: Bailian@2025"
        echo -e "  Redis: 端口6379, 密码: Redis@2025"
        echo -e "  NGINX: 端口80, 地址: http://$(hostname -i)"
        echo -e "  Tomcat: 端口8080, 地址: http://$(hostname -i):8080"
        echo -e "${BLUE}部署日志:${NC} $LOG_FILE"
        echo -e "${BLUE}备份目录:${NC} $BACKUP_DIR"
    else
        error_log "以下服务部署失败: ${failed_deployments[*]}"
        echo -e "${RED}部分服务部署失败，请检查日志: $LOG_FILE${NC}"
        echo -e "${YELLOW}建议检查:${NC}"
        echo -e "  1. 确保所有软件包已正确解压到 $INSTALL_BASE 目录"
        echo -e "  2. 检查系统日志: journalctl -u mysql/nginx/tomcat/redis"
        echo -e "  3. 检查服务日志文件"
    fi
    
    cleanup
}

# 信号处理
trap 'log "收到中断信号，正在清理..."; cleanup; exit 1' INT TERM

# 执行主函数
main "$@"
